<template>
  <div 
    class="pull-refresh-container" 
    :style="containerStyle"
    @touchstart="handleTouchStart"
    @touchmove="handleTouchMove"
    @touchend="handleTouchEnd"
  >
    <!-- 下拉刷新指示器 -->
    <div 
      class="pull-refresh-indicator" 
      :style="{ height: isPulling ? progress * 0.8 + 'px' : '0px' }"
    >
      <div 
        class="refresh-spinner" 
        :class="{ spinning: isRefreshing }" 
        :style="{ transform: `rotate(${isRefreshing ? '360deg' : progress * 3.6 + 'deg'})` }"
      ></div>
      <span v-if="isRefreshing">{{ refreshingText }}</span>
      <span v-else-if="isPulling">{{ progress >= threshold ? releaseText : pullText }}</span>
    </div>
    
    <!-- 内容区域 -->
    <div class="pull-refresh-content" :style="contentStyle">
      <slot></slot>
    </div>
  </div>
</template>

<script>
export default {
  name: 'PullRefresh',
  props: {
    threshold: {
      type: Number,
      default: 100, // 触发刷新的阈值
    },
    pullText: {
      type: String,
      default: '下拉刷新',
    },
    releaseText: {
      type: String,
      default: '释放刷新',
    },
    refreshingText: {
      type: String,
      default: '刷新中...',
    },
    resistance: {
      type: Number,
      default: 0.8, // 下拉阻力系数
    },
  },
  data() {
    return {
      isPulling: false,
      isRefreshing: false,
      progress: 0,
      startY: 0,
      isTouching: false,
    }
  },
  computed: {
    containerStyle() {
      return {}
    },
    contentStyle() {
      if (this.isPulling && !this.isRefreshing) {
        return {
          transform: `translateY(${this.progress * this.resistance}px)`,
        }
      }
      return {}
    },
  },
  methods: {
    handleTouchStart(event) {
      // 只有当页面滚动到顶部时才能触发下拉刷新
      if (window.scrollY <= 0 && !this.isRefreshing) {
        this.isTouching = true
        this.startY = event.touches[0].clientY
      }
    },
    handleTouchMove(event) {
      if (!this.isTouching || this.isRefreshing) return
      
      const currentY = event.touches[0].clientY
      const pullDistance = currentY - this.startY
      
      // 只有向下拉才能触发
      if (pullDistance > 0 && window.scrollY <= 0) {
        event.preventDefault() // 阻止默认滚动行为
        this.isPulling = true
        this.progress = Math.min(pullDistance, this.threshold * 1.5) // 限制最大下拉距离
      }
    },
    handleTouchEnd() {
      if (!this.isTouching || this.isRefreshing) return
      
      this.isTouching = false
      
      if (this.isPulling) {
        if (this.progress >= this.threshold) {
          // 触发刷新
          this.startRefresh()
        } else {
          // 回弹
          this.resetPull()
        }
      }
    },
    startRefresh() {
      this.isRefreshing = true
      this.progress = this.threshold
      
      // 发出刷新事件
      this.$emit('refresh')
    },
    resetPull() {
      this.isPulling = false
      this.progress = 0
    },
    // 外部调用此方法完成刷新
    completeRefresh() {
      setTimeout(() => {
        this.isRefreshing = false
        this.resetPull()
        this.$emit('refresh-complete')
      }, 300) // 给用户一点视觉反馈时间
    },
    // 阻止刷新
    abortRefresh() {
      this.isRefreshing = false
      this.resetPull()
      this.$emit('refresh-abort')
    },
  },
}
</script>

<style scoped>
.pull-refresh-container {
  overflow: hidden;
  position: relative;
  min-height: 100%;
}

.pull-refresh-indicator {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  transition: height 0.3s ease;
}

.refresh-spinner {
  width: 24px;
  height: 24px;
  border: 2px solid #e0e0e0;
  border-top: 2px solid var(--bilibili-pink, #FB7299);
  border-radius: 50%;
  margin-bottom: 8px;
  transition: transform 0.2s ease;
}

.refresh-spinner.spinning {
  animation: spin 0.8s linear infinite;
}

.pull-refresh-content {
  transition: transform 0.3s ease;
  will-change: transform;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* 响应式调整 */
@media (max-width: 768px) {
  .refresh-spinner {
    width: 20px;
    height: 20px;
    border-width: 2px;
  }
}
</style>